package com.mybatis.generate.generator;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.mybatis.generate.provider.db.DbTableFactory;
import com.mybatis.generate.provider.db.DbTableGeneratorModelProvider;
import com.mybatis.generate.provider.db.model.Table;
import com.mybatis.generate.provider.java.JavaClassGeneratorModelProvider;
import com.mybatis.generate.provider.java.model.JavaClass;
import com.mybatis.generate.util.StringHelper;

public class GeneratorFacade {
	public Map<String,Object> tableMaps;
	public Map<String,Object> excludeMaps;
	private String rootPath;

	public GeneratorFacade(String fileName,String rootPath) {
		this.rootPath = rootPath;
		initProperties(fileName);
	}
	
	public void printAllTableNames() throws SQLException {
		List tables = DbTableFactory.getInstance().getAllTables();
		System.out.println("\n----All TableNames BEGIN----");
		for(int i = 0; i < tables.size(); i++ ) {
			String sqlName = ((Table)tables.get(i)).getSqlName();
			System.out.println("g.generateTable(\""+sqlName+"\");");
		}
		System.out.println("----All TableNames END----");
	}
	
	public void generateByAllTable(String templateUrl) throws Exception {
		List<Table> tables = DbTableFactory.getInstance().getAllTables();
		for(int i = 0; i < tables.size(); i++ ) {
			generateByTable(tables.get(i).getSqlName());
		}
	}

	public void generateByTable(String tableName) throws Exception {
		Generator g = createGeneratorForDbTable();
		Table table = DbTableFactory.getInstance().getTable(tableName);
		String excludeObjectNames = (String)this.excludeMaps.get(tableName);
		g.generateByModelProvider(new DbTableGeneratorModelProvider(table),excludeObjectNames);
	}
	
	public void generateByTable(String tableName,String className) throws Exception {
		Generator g = createGeneratorForDbTable();
		Table table = DbTableFactory.getInstance().getTable(tableName);
		String excludeObjectNames = (String)this.excludeMaps.get(tableName);
		if(StringHelper.isNotEmpty(className)) {
			table.setClassName(className);
		}
		g.generateByModelProvider(new DbTableGeneratorModelProvider(table),excludeObjectNames);
	}
	
	public void generateByClass(Class clazz) throws Exception {
		Generator g = createGeneratorForJavaClass();
		g.generateByModelProvider(new JavaClassGeneratorModelProvider(new JavaClass(clazz)),"");
	}
	
	public void clean() throws IOException {
		Generator g = createGeneratorForDbTable();
		g.clean();
	}

	private Generator createGeneratorForDbTable() {
		Generator g = new Generator();
		// 使用generate中ftl模板生成
		//g.setTemplateRootDir(new File(GeneratorFacade.class.getResource("").getPath().replace("generator", "template")));
		// 使用项目中自定义的模板生成
		g.setTemplateRootDir(new File(this.rootPath+ GeneratorProperties.getRequiredProperty("template_url")));
		g.setOutRootDir(GeneratorProperties.getRequiredProperty("outRoot"));
		return g;
	}
	
	private Generator createGeneratorForJavaClass() {
		Generator g = new Generator();
		g.setTemplateRootDir(new File("template/javaclass").getAbsoluteFile());
		g.setOutRootDir(GeneratorProperties.getRequiredProperty("outRoot"));
		return g;
	}
	
	private void initProperties(String fileName) {
		SAXReader saxReader = new SAXReader();
		try {
            Document document = saxReader.read(GeneratorFacade.class.getClassLoader().getResourceAsStream(fileName));
            Element root = document.getRootElement();
            Element generate = (Element)root.elements().get(0);
            
            //设置generator.properties属性值
            GeneratorProperties.setProperty("jdbc.driver", generate.attributeValue("driverClass"));
            GeneratorProperties.setProperty("jdbc.url", generate.attributeValue("connectionURL"));
            GeneratorProperties.setProperty("jdbc.username", generate.attributeValue("userName"));
            GeneratorProperties.setProperty("jdbc.password", generate.attributeValue("password"));
            GeneratorProperties.setProperty("basepackage", generate.attributeValue("basePackage"));
            GeneratorProperties.setProperty("template_url", generate.attributeValue("templateUrl"));
            if(StringHelper.isNotEmpty(generate.attributeValue("outRoot"))) {
            	GeneratorProperties.setProperty("outRoot", this.rootPath + generate.attributeValue("outRoot"));
            }
            
            //查询所有的table
            List<Element> tableEles = generate.elements();
            if(!tableEles.isEmpty() && tableEles.size() > 0) {
            	tableMaps = new HashMap<String,Object>();
            	excludeMaps = new HashMap<String,Object>();
            	for (int i = 0, length = tableEles.size(); i < length; i++) {
            		String domainObjectName = tableEles.get(i).attributeValue("domainObjectName");
            		String excludeObjectNames = tableEles.get(i).attributeValue("excludeObjectNames");
            		if(!StringHelper.isNotEmpty(domainObjectName)) {
            			domainObjectName = "";
            		}
            		if(!StringHelper.isNotEmpty(excludeObjectNames)) {
            			excludeObjectNames = "";
            		}
            		tableMaps.put(tableEles.get(i).attributeValue("tableName"), domainObjectName);
            		excludeMaps.put(tableEles.get(i).attributeValue("tableName"), excludeObjectNames);
				}
            }
        } catch (DocumentException e) {
            System.out.println(e.getMessage());
        }
	}
}
